/*
 * author      : dormi330
 * date        : 2018/6/26
 * description : 订单相关查询
 */

package com.deep.trade.application.order;

import com.deep.trade.adaptor.required.logistical.LogisticalService;
import com.deep.trade.adaptor.required.member.Member;
import com.deep.trade.common.CommonUtils;
import com.deep.trade.common.TradeException;
import com.deep.trade.domain.order.*;
import com.deep.trade.order.dto.*;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class OrderQueryService {

    @Autowired
    private OrderQueryRepository orderQueryRepository;

    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());

    @Autowired
    private LogisticalService logisticalService;

    /**
     * 获取 TradeOrder 订单, 并确保存在
     */
    public TradeOrder assureTradeOrder(String tradeOrderId) throws Exception {
        TradeOrder tradeOrder = orderQueryRepository.tradeOrderOfId(tradeOrderId);
        if (null == tradeOrder) throw new TradeException("no such tradeOrder, tradeOrderId=" + tradeOrderId);
        return tradeOrder;
    }

    /**
     * 用户查询 - OrderSummary 列表
     */
    public PageInfo<OutDtoOrderSummary> orderSummaryOfMember(Member member, int pageNum, int pageSize) throws Exception {
        logger.info("{}, tenantCode={}, memberId={}", CommonUtils.currentClassAndMethod(), member);
        if (null == member) throw new TradeException("memberId cannot be null");
        PageInfo<OrderSummary> orderSummaryPageInfo = orderQueryRepository.orderSummaryOfMember(member.getId(), pageNum, pageSize);
        return CommonUtils.entity2Dto(orderSummaryPageInfo, OutDtoOrderSummary.class);
    }

    /** 分页获取 某个租户对所有 订单 */
    public PageInfo<OutDtoTradeOrder> tradeOrderListOfTenant(int pageNum, int pageSize) throws Exception {
        logger.info("{}, tenantCode={}", CommonUtils.currentClassAndMethod());
        PageInfo<TradeOrder> tradeOrderPageInfo = orderQueryRepository.tradeOrderOfTenant(pageNum, pageSize);
        return CommonUtils.entity2Dto(tradeOrderPageInfo, OutDtoTradeOrder.class);
    }

    /** 获取用户的订单列表 done */
    public PageInfo<OutDtoTradeOrder> tradeOrderListOfMember(Member member, int pageNum, int pageSize) throws Exception {
        logger.info("{}, member={}", CommonUtils.currentClassAndMethod(), member);
        if (null == member) throw new TradeException("memberId cannot be null");

        PageInfo<TradeOrder> tradeOrderPageInfo = orderQueryRepository.tradeOrderOfMember(member.getId(), pageNum, pageSize);
        return CommonUtils.entity2Dto(tradeOrderPageInfo, OutDtoTradeOrder.class);
    }

    /** 获取用户的订单列表 done */
    public PageInfo<OutDtoTradeOrderWithSku> tradeOrderWithSkuListOfMember(Member member, int pageNum, int pageSize) throws Exception {
        logger.info("{}, tenantCode={}, memberId={}", CommonUtils.currentClassAndMethod(), member);
        if (null == member) throw new TradeException("memberId cannot be null");

        PageInfo<TradeOrder> tradeOrderPageInfo = orderQueryRepository.tradeOrderOfMember(member.getId(), pageNum, pageSize);
        List<TradeOrder> tradeOrderList = tradeOrderPageInfo.getList();
        if (tradeOrderList.size() == 0) {
            return new PageInfo<>(null);
        }

        // 查询这些 tradeorder的 TradeOrderSku
        List<String> idList = new ArrayList<>();
        for (TradeOrder tradeOrder : tradeOrderList) {
            String tradeOrderId = tradeOrder.getId();
            idList.add(tradeOrderId);
        }
        List<TradeOrderSku> tradeOrderSkuList = orderQueryRepository.orderSkuOfTradeOrderList(idList);
        List<OutDtoOrderSku> outDtoOrderSkuList = CommonUtils.entity2Dto(tradeOrderSkuList, OutDtoOrderSku.class);

        // map eo -> dto
        Map<String, OutDtoTradeOrderWithSku> orderWithSkuMap = new HashMap<>();
        List<OutDtoTradeOrderWithSku> outDtoTradeOrderList = CommonUtils.entity2Dto(tradeOrderPageInfo.getList(), OutDtoTradeOrderWithSku.class);
        outDtoTradeOrderList.forEach(outDtoTradeOrderWithSku -> {
            orderWithSkuMap.put(outDtoTradeOrderWithSku.getId(), outDtoTradeOrderWithSku);
        });

        outDtoOrderSkuList.forEach(outDtoOrderSku -> {
            String tradeOrderId = outDtoOrderSku.getTradeOrderId();
            orderWithSkuMap.get(tradeOrderId).addOutDtoOrderSku(outDtoOrderSku);
        });

        return new PageInfo<>(outDtoTradeOrderList);
    }

    /** 获取订单详情 done */
    public OutDtoOrderDetail tradeOrderDetail(String tradeOrderId) throws Exception {
        logger.info("{}, tenantCode={}, tradeOrderId={}", CommonUtils.currentClassAndMethod(), tradeOrderId);
        if (null == tradeOrderId) throw new TradeException("tradeOrderId cannot be null");

        TradeOrder tradeOrder = orderQueryRepository.tradeOrderOfId(tradeOrderId);
        if (null == tradeOrder) throw new TradeException("tradeOrder cannot be found");

        // tradeOrder
        OutDtoTradeOrder outDtoTradeOrder = new OutDtoTradeOrder();
        BeanUtils.copyProperties(tradeOrder, outDtoTradeOrder);

        // 收货地址
        DeliveryAddress deliveryAddress = orderQueryRepository.orderDeliveryOfTradeOrder(tradeOrderId);
        OutDtoOrderDelivery outDtoOrderDelivery = new OutDtoOrderDelivery();
        BeanUtils.copyProperties(deliveryAddress, outDtoOrderDelivery);

        // 支付信息
        OrderPayment orderPayment = orderQueryRepository.paymentOfTradeOrder(tradeOrderId);
        OutDtoOrderPayment outDtoOrderPayment = new OutDtoOrderPayment();
        if (null != orderPayment) BeanUtils.copyProperties(orderPayment, outDtoOrderPayment);

        // 订单中的sku
        List<TradeOrderSku> tradeOrderSkuList = orderQueryRepository.orderSkuOfTradeOrder(tradeOrderId);
        List<OutDtoOrderSku> outDtoOrderSkuList = CommonUtils.entity2Dto(tradeOrderSkuList, OutDtoOrderSku.class);

        // 包裹信息
        List<OrderParcel> orderParcelList = orderQueryRepository.parcelListOfOrder(tradeOrderId);
        List<OutDtoOrderParcel> outDtoOrderParcelList = null;
        if (orderParcelList.size() > 0) {
            outDtoOrderParcelList = CommonUtils.entity2Dto(orderParcelList, OutDtoOrderParcel.class);
            // 物流信息
            outDtoOrderParcelList.forEach(outDtoOrderParcel -> {
                List<OutDtoLogisticalRecord> recordList = logisticalService.listOfTrackingNo(outDtoOrderParcel.getTrackingNo());
                outDtoOrderParcel.setLogisticalRecordList(recordList);
            });
        }


        return new OutDtoOrderDetail(outDtoOrderDelivery, outDtoOrderSkuList, outDtoTradeOrder, outDtoOrderPayment, outDtoOrderParcelList);
    }
}
